<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Operation\Event;

use Admin\Data\Common;
use Doctrine\ORM\EntityManager;
use Laminas\EventManager\Event;
use Laminas\EventManager\EventManagerInterface;
use Laminas\EventManager\ListenerAggregateInterface;
use Laminas\I18n\Translator\Translator;
use Operation\Entity\UserCoupon;
use Operation\Service\Common\Coupon;
use Operation\Service\Common\Discount;
use Operation\Service\UserCouponManager;

class OperationListener implements ListenerAggregateInterface
{
    protected $listeners = [];

    private $entityManager;
    private $translator;
    private $userCouponManager;

    public function __construct(
        EntityManager   $entityManager,
        UserCouponManager $userCouponManager
    )
    {
        $this->entityManager    = $entityManager;
        $this->userCouponManager= $userCouponManager;

        $this->translator       = new Translator();
    }

    public function attach(EventManagerInterface $events, $priority = 1)
    {
        $shareEvents = $events->getSharedManager();

        //前台商品详情，显示信息
        $this->listeners[] = $shareEvents->attach(
            'Shop\Controller\GoodsController', 'shop.goodsInfo.goods.show', [$this, 'onGoodsInfoShow'], 100
        );

        //后台会员添加，初始化积分
        $this->listeners[] = $shareEvents->attach(
            'User\Controller\IndexController', 'backstage-user.add.post', [$this, 'onAddUserCoupon']
        );
        //前台会员注册完成，发送优惠券
        $this->listeners[] = $shareEvents->attach(
            'Shop\Controller\UserController', 'shop.user.register.post', [$this, 'onAddUserCoupon'], 100
        );

        //结账，显示可用的优惠券
        $this->listeners[] = $shareEvents->attach(
            'Shop\Controller\CheckoutController', 'shop.checkout.one.post', [$this, 'onUserCouponList']
        );

        //前台确认订单时，如存在获取优惠券则进行优惠券可用处理
        $this->listeners[] = $shareEvents->attach(
            'Shop\Controller\HomeOrderController', 'shop.order.receipt.post', [$this, 'onUserCouponChange'], 90
        );
        //后台确认订单时，如存在获取优惠券则进行优惠券可用处理
        $this->listeners[] = $shareEvents->attach(
            'Sales\Controller\IndexController', 'backstage-order.receipt.post', [$this, 'onUserCouponChange'], 90
        );
    }

    public function detach(EventManagerInterface $events)
    {
        foreach ($this->listeners as $index => $listener) {
            $events->detach($listener);
            unset($this->listeners[$index]);
        }
    }

    /**
     * 显示可获取的优惠券
     * @param Event $event
     * @return array|array[]
     */
    public function onGoodsInfoShow(Event $event)
    {
        $goodsInfo  = $event->getParam('goodsInfo');

        //优惠券
        $userGroupId= $event->getTarget()->shopPlugin()->getUserLoginData('user_group_id');
        $couponArray= Coupon::clickCouponList(['userGroupId' => $userGroupId, 'classId' => $goodsInfo[0]->getClassId(), 'brandId' => $goodsInfo[0]->getBrandId()]);

        //优惠促销
        $discountArray = Discount::goodsDiscount(['userGroupId' => $userGroupId, 'classId' => $goodsInfo[0]->getClassId(), 'brandId' => $goodsInfo[0]->getBrandId()], $this->translator);

        $event->setParams(array_merge($event->getParams(), ['lastArray' => ['couponArray' => $couponArray, 'discountArray' => $discountArray]]));

        return ['couponArray' => $couponArray, 'discountArray' => $discountArray];
    }

    /**
     * 注册获取优惠券
     * @param Event $event
     * @return string
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function onAddUserCoupon(Event $event)
    {
        $couponConfig = Common::readConfigFile('coupon');
        if (empty($couponConfig)) return '';

        $userInfo   = $event->getParam('user');
        foreach ($couponConfig as $coupon) {
            if (!Common::checkTime($coupon['getCouponStartTime'], $coupon['getCouponEndTime']) || $coupon['getCouponType'] != 'register') continue;

            $userCouponInfo = $this->entityManager->getRepository(UserCoupon::class)->findOneBy(['userId' => $userInfo->getUserId(), 'couponId' => $coupon['couponId']]);
            if ($userCouponInfo) continue;

            $addUserCoupon = [
                'couponUseState' => 1,
                'userId'        => $userInfo->getUserId(),
                'userName'      => $userInfo->getUserName(),
                'getTime'       => time(),
                'couponId'      => $coupon['couponId'],
                'couponTitle'   => $coupon['couponTitle'],
                'couponInfo'    => $coupon['couponInfo'],
                'couponUseStartTime'=> $coupon['couponStartTime'],
                'couponUseEndTime'  => $coupon['couponEndTime']
            ];

            $this->userCouponManager->addUserCoupon($addUserCoupon);
        }
    }

    /**
     * 会员可用的优惠券（提交订单页面及提交操作）
     * @param Event $event
     * @return mixed|null
     */
    public function onUserCouponList(Event $event)
    {
        $array      = $event->getParams();
        $userId     = $event->getParam('userId');
        $userInfo   = $event->getParam('user');
        $lastArray  = $event->getParam('lastArray');
        $postArray  = $event->getParam('postArray');//只要在提交订单的时候，才会有postArray，其他处理时，不传值

        $couponIdArray  = Coupon::useCouponIdArray(['cartGoodsList' => $lastArray['cartGoodsList']]);

        $userCouponList     = '';
        $couponPriceArray   = [];
        if (!empty($couponIdArray)) {
            $userCouponList = $this->entityManager->getRepository(UserCoupon::class)->checkoutUserCouponList($userId, $couponIdArray);
            if ($userCouponList) foreach ($userCouponList as $couponValue) {
                $couponPriceArray[$couponValue[0]->getCouponId()] = $couponValue['shoppingDiscount'];
            }
        }

        //提交订单，判断是否有优惠券可用
        if (isset($postArray['couponId']) && $postArray['couponId'] > 0) {
            $userCouponInfo = $this->entityManager->getRepository(UserCoupon::class)->findOneBy(['couponId' => $postArray['couponId'], 'userId' => $userId, 'couponUseState' => 1]);
            if (
                $userCouponInfo
                && !empty($couponPriceArray)
                && isset($couponPriceArray[$postArray['couponId']])
                && $couponPriceArray[$postArray['couponId']] > 0
                && $lastArray['orderAmount'] >= $couponPriceArray[$postArray['couponId']]
            ) {
                $lastArray['userCouponInfo']= $userCouponInfo;
                $lastArray['orderAmount']   = $lastArray['orderAmount'] - $couponPriceArray[$postArray['couponId']];
                $lastArray['orderCoupon']   = [
                    'couponPrice'   => $couponPriceArray[$postArray['couponId']],
                    'couponTitle'   => $this->translator->translate('优惠券优惠'),
                    'couponId'      => $postArray['couponId']
                ];
            }
        }
        //提交订单，判断是否有优惠券可以领取
        if (!empty($postArray)) {
            $addUserCouponArray = Coupon::addOrderGetCoupon(['cartGoodsList' => $lastArray['cartGoodsList'], 'userGroupId' => $event->getParam('userGroupId')]);
            if (!empty($addUserCouponArray)) $lastArray['addUserCoupon'] = $addUserCouponArray;
        }

        $lastArray['useCouponList']     = $userCouponList;
        $lastArray['couponPriceArray']  = $couponPriceArray;
        $array['lastArray']             = $lastArray;
        $event->setParams($array);

        return $lastArray;
    }

    /**
     * 确定订单时，如存在获取优惠券则进行优惠券可用处理
     * @param Event $event
     */
    public function onUserCouponChange(Event $event)
    {
        $orderInfo = $event->getParam('orderInfo');
        $this->userCouponManager->updateOrderGetUserCoupon($orderInfo->getOrderId(), $orderInfo->getUserId());
    }
}